home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
10.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
51KB
|
1,684 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
#include "hdr.h"
#include "libhdr.h"
#include "vars.h"
#include "ifile.h"
#include "chapp.h"
#include "setp.h"
#include "smiscp.h"
#include "miscp.h"
#include "libp.h"
#include "libwp.h"
#include "dclmapp.h"
#include "dbxp.h"
#include "errmsgp.h"
int save_trace_opt = 0;
/* chapter 10 */
static Tuple context;
static void init_compunit();
static void save_comp_info(Node);
static void save_tree(Node, int);
static void renumber_nodes(char *);
static void collect_unit_nodes(Symbol);
static void generic_declarations(Symbol, Unitdecl);
static void save_proper_body_info(Node);
static void save_package_instance_unit(Node);
static void save_subprogram_instance_unit(Node);
static void establish_context(Node);
static void with_clause(Tuple, Node);
static void elaborate_pragma(Node);
static Tuple check_separate(Node);
static Stubenv retrieve_env(Node, Node);
static void remove_obsolete_stubs(char *);
static char *get_unit(char *);
static void new_unit_numbers(Node, unsigned);
/*TBSL: need to review calls to sasve_subprog_info now that
* it has an argument ds 31 oct
*/
extern IFILE *TREFILE, *AISFILE, *LIBFILE;
static Tuple elab_pragmas;
/* all_vis is tuple of unit-names */
static void init_compunit() /*;init_compunit*/
{
int i;
if (cdebug2 > 3) TO_ERRFILE("AT PROC : init_compunit;");
/* Initialize tree nodes to unit number of the new compilation unit.*/
unit_number_now = unit_number(unit_name);
for (i = 1; i <= seq_node_n; i++)
N_UNIT((Node)seq_node[i]) = unit_number_now;
}
void new_compunit(char *typ, Node name_node) /*;new_compunit*/
{
char *name;
if (cdebug2 > 3) TO_ERRFILE("AT PROC : new_compunit");
name = N_VAL(name_node);
/* Establish global name and library name for new compilation unit. */
if (IS_COMP_UNIT){
remove_obsolete_stubs(name);
seq_symbol_n = 0; /* reset symbol count */
unit_name = strjoin(typ, name);
init_compunit();
}
}
/* chapter 10, part b*/
void compunit(Node node) /*;compunit*/
{
Node unit_body;
Tuple added_names;
char *id;
Fortup ft1;
Symbol sym;
Fordeclared fd;
if (cdebug2 > 3) TO_ERRFILE("AT PROC : compunit;");
elab_pragmas = tup_new(0);
stubs_to_write = set_new(0);
all_vis = tup_new(0);
/*context_node = N_AST1(node);*/
unit_body = N_AST2(node);
establish_context(node);
/* process unit only if there were no problems in processing context */
if (context != (Tuple)0)
adasem(unit_body);
if (errors == 0) {
/* If there are no errors in any comp unit in the file, collect global
* maps and library information after completion of this a compilation
* unit.
*/
if (N_KIND(unit_body) == as_separate)
/* collect symbol table information for body (it is not a unit,
* and must be saved explicitly here).
*/
save_proper_body_info(unit_body);
tup_frome(newtypes);
if (N_KIND(unit_body) == as_insert) {
if (N_KIND(N_AST1(unit_body)) == as_subprogram_tr)
/* for a subprogram instance, we place renaming code in the body
* of the subprogram. If there is some additional instantiation
* code (bounds checks, etc.) it must be placed in a separate
* unit on which the instantiation depends.
*/
save_subprogram_instance_unit(node);
else
/* Produce two units, one for spec instance and one for body. */
save_package_instance_unit(node);
}
else { /* any other kind of compilation unit.*/
save_comp_info(node);
}
}
/* Reinitialize compilation environment. */
unit_name = strjoin("","");
newtypes = tup_with(newtypes, (char *) tup_new(0));
/* DECLARED := BASE_DECLARED;
* Delete symbols placed in standard0 by previous compilation,
* restoring standard0 to its initial state. added_names is a tuple
* of identifiers added in prior compilation.
*/
added_names = tup_new(0); /* build tuple of added identifiers */
FORDECLARED(id, sym, DECLARED(symbol_standard0), fd);
if (sym != (Symbol)0 && S_UNIT(sym))
added_names = tup_with(added_names, id);
ENDFORDECLARED(fd);
FORTUP(id=(char *), added_names, ft1);
dcl_undef(DECLARED(symbol_standard0), id);
ENDFORTUP(ft1);
tup_free(added_names);
DECLARED(symbol_unmentionable) = base_declared[1];
DECLARED(symbol_standard) = base_declared[2];
DECLARED(symbol_ascii) = base_declared[3];
FORDECLARED(id, sym, DECLARED(symbol_ascii), fd);
IS_VISIBLE(fd) = TRUE;
ENDFORDECLARED(fd);
scope_name = symbol_standard0;
open_scopes = tup_new(2);
open_scopes[1] = (char *)symbol_standard0;
open_scopes[2] = (char *)symbol_unmentionable;
used_mods = tup_new(0);
vis_mods = tup_new1((char *) symbol_ascii);
scope_st = tup_new(0);
return;
}
static void save_comp_info(Node node) /*;save_comp_info*/
{
/* Subsidiary to the previous procedure. In the case of a unit which is
* a package instantiation, the current procedure is called twice, to
* produce separate units for the instance spec and the instance body.
*/
Unitdecl ud;
char *v;
Tuple tup;
Set vis_units;
int uindex, i, si;
struct unit *pUnit;
Fortup ft1;
Forset fs1;
Stubenv ev;
char *stub_name;
vis_units = set_new(tup_size(all_vis));
uindex = unit_number(unit_name);
pUnit = pUnits[uindex];
/*PRE_COMP(unit_name) := vis_units;*/
FORTUP(v=(char *), all_vis, ft1);
vis_units = set_with(vis_units, (char *) unit_numbered(v));
ENDFORTUP(ft1);
pUnit->aisInfo.preComp = (char *)vis_units;
pUnit->aisInfo.pragmaElab = (char *) tup_copy(elab_pragmas);
/* Before writing out any info, set unit of all symbols allocated
* while compiling this unit to current unit number
*/
for (i = 1; i <= seq_symbol_n; i++)
S_UNIT((Symbol)seq_symbol[i]) = uindex;
save_tree(node, uindex);
update_lib_maps(unit_name, 'u');
pUnit->aisInfo.compDate = (char *) tup_new(0);
/*UNIT_DECL(unit_name) +:= [CONTEXT, UNIT_NODES]; */
ud = unit_decl_get(unit_name);
if (ud == (Unitdecl)0)
chaos("save_comp_info: unit decl missing");
ud->ud_context = tup_copy(context);
ud->ud_nodes = tup_copy(unit_nodes);
unit_decl_put(unit_name, ud);
if (!errors) {
/* Stub environment info is now written after the tree nodes
* are renumbered in save_tree. Also in case of erros Stub info
* is not written to st1 file.
*/
FORSET(si=(int), stubs_to_write, fs1)
stub_name = lib_stub[si];
tup = (Tuple) stub_info[si];
ev = (Stubenv) tup[2];
write_stub(ev, stub_name, "st1");
ENDFORSET(fs1);
}
if (!errors) write_ais(uindex);
}
static void new_unit_numbers(Node root, unsigned newUnitNumber)
/*;new_unit_number*/
{
unsigned nodeKind;
Node listNode;
Fortup ft1;
Tuple listTuple;
if (root == (Node)0 || root == OPT_NODE) return;
N_UNIT(root) = newUnitNumber;
nodeKind = N_KIND(root);
if (N_AST1_DEFINED(nodeKind)) new_unit_numbers(N_AST1(root), newUnitNumber);
if (N_AST2_DEFINED(nodeKind)) new_unit_numbers(N_AST2(root), newUnitNumber);
if (N_AST3_DEFINED(nodeKind)) new_unit_numbers(N_AST3(root), newUnitNumber);
if (N_AST4_DEFINED(nodeKind)) new_unit_numbers(N_AST4(root), newUnitNumber);
if (! N_LIST_DEFINED(nodeKind)) return;
listTuple = N_LIST(root);
FORTUP(listNode=(Node), listTuple, ft1);
new_unit_numbers(listNode, newUnitNumber);
ENDFORTUP(ft1);
}
static void save_tree(Node root, int uindex) /*;save_tree*/
{
/* This procedure builds a sequential list of all the nodes in the
* abstract syntax tree while performing a preorder scan of the tree.
* For a given node, all its components are placed in a flat tuple
* "tree_node". This tuple is then added to the list.
*
* For the C version, we need to traverse the tree to find the reachable
* nodes, which are built up in a string reach such that reach[i] is
* 1 if node with sequence number i is reachable, 0 otherwise.
* We then call write_tree (lib.c) to actually write the tree.
*/
int stack_max, stack_now, na, i, unit_now, nk;
Tuple stack, a;
Node nodes[5], n, nod;
char *reach;
#define STACK_INC 50
if (TREFILE == (IFILE *)0) return;
reach = emalloct((unsigne